#include <QSettings>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QSignalMapper>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QFileDialog>
#include <QMessageBox>

#include "DocViews/aisdocview.h"
#include "SpeechAgent/aispeechagent.h"
#include "SpeechAgent/aisiflytekagent.h"
#include "AudioRender/aisaudiorender.h"

#include "mainwindow.h"

#define KEY_SETTING_POS "position"
#define KEY_SETTING_SIZE "size"
#define KEY_SETTING_RUFOLDER "recentUsedFolder"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    initCentralWidget();
    initAction();
    initMenuBar();

    loadSetting();
    setWindowTitle(tr("AISReader - aiseminar.cn"));
    initSpeechAgent();
    initAudioRender();
}

MainWindow::~MainWindow()
{
    uninitSpeechAgent();
}

void MainWindow::closeEvent(QCloseEvent *)
{
    saveSetting();
}

void MainWindow::saveSetting()
{
    QSettings settings(NAME_ORGANIZATION, NAME_APPLICATION);
    settings.setValue(KEY_SETTING_POS, pos());
    settings.setValue(KEY_SETTING_SIZE, size());
    settings.setValue(KEY_SETTING_RUFOLDER, recentUsedFolder);
}

void MainWindow::loadSetting()
{
    QSettings settings(NAME_ORGANIZATION, NAME_APPLICATION);
    QPoint position = settings.value(KEY_SETTING_POS, QPoint(200, 200)).toPoint();
    QSize size = settings.value(KEY_SETTING_SIZE, QSize(400, 400)).toSize();
    recentUsedFolder = settings.value(KEY_SETTING_RUFOLDER, QString()).toString();
    move(position);
    resize(size);
}

void MainWindow::initCentralWidget()
{
    mdiArea = new QMdiArea();
    mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setCentralWidget(mdiArea);
    connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(updateMenus()));
    signalMapper = new QSignalMapper(this);
    connect(signalMapper, SIGNAL(mapped(QWidget*)), this, SLOT(setActiveSubWindow(QWidget *)));
}

void MainWindow::initAction()
{
    newFileAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
    newFileAct->setShortcut(QKeySequence::New);
    newFileAct->setStatusTip(tr("New a text file"));
    connect(newFileAct, SIGNAL(triggered()), this, SLOT(newFile()));

    openFileAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
    openFileAct->setShortcut(QKeySequence::Open);
    openFileAct->setStatusTip(tr("Open an existing file"));
    connect(openFileAct, SIGNAL(triggered()), this, SLOT(openFile()));

    saveFileAct = new QAction(QIcon(":/images/save.png"), tr("&save"), this);
    saveFileAct->setShortcut(QKeySequence::Save);
    saveFileAct->setStatusTip(tr("Save the changes to file"));
    connect(saveFileAct, SIGNAL(triggered()), this, SLOT(saveFile()));

    startSpeakingAct = new QAction(tr("Start Speaking"), this);
    startSpeakingAct->setStatusTip(tr("Speak the selected text"));
    connect(startSpeakingAct, SIGNAL(triggered()), this, SLOT(startSpeaking()));

    stopSpeakingAct = new QAction(tr("Stop Speaking"), this);
    stopSpeakingAct->setStatusTip(tr("Stop the speaking"));
    connect(stopSpeakingAct, SIGNAL(triggered()), this, SLOT(stopSpeaking()));

    speechSettingAct = new QAction(tr("Speech &Setting"), this);
    speechSettingAct->setStatusTip(tr("Set speech options"));
    connect(speechSettingAct, SIGNAL(triggered()), this, SLOT(speechSetting()));
}

void MainWindow::initMenuBar()
{
    QMenuBar *mainMenuBar = menuBar();

    fileMenu = mainMenuBar->addMenu(tr("&File"));
    fileMenu->addAction(newFileAct);
    fileMenu->addAction(openFileAct);
    fileMenu->addAction(saveFileAct);

    speechMenu = mainMenuBar->addMenu(tr("&Speech"));
    speechMenu->addAction(startSpeakingAct);
    speechMenu->addAction(stopSpeakingAct);
    speechMenu->addSeparator();
    speechMenu->addAction(speechSettingAct);
}

void MainWindow::initSpeechAgent()
{
    speechAgent = new AISIflytekAgent;
    speechAgent->initTTSEngine();
}

void MainWindow::uninitSpeechAgent()
{
    if (speechAgent)
    {
        speechAgent->uninitTTSEngine();
        speechAgent = NULL;
    }
}

void MainWindow::initAudioRender()
{
    audioRender = new AISAudioRender;
}

void MainWindow::uninitAudioRender()
{
    if (audioRender)
    {
        audioRender = NULL;
    }
}

void MainWindow::updateMenus()
{
}

void MainWindow::newFile()
{
    AISDocView *docView = new AISDocView;
    mdiArea->addSubWindow(docView);
    if (docView->newFile("aisReader.txt"))
    {
        docView->showMaximized();
    }
    else
    {
        docView->close();
    }
}

void MainWindow::openFile()
{
    if (recentUsedFolder.isEmpty())
    {
        recentUsedFolder = "~/Document";
    }

    QString filePath = QFileDialog::getOpenFileName(this,
                                                    tr("Open File"), recentUsedFolder, tr("All files (*.*);;Text files (*.txt *.xml);;Word (*.doc *docx);;PPT (*.ppt *.pptx);;EXCEL (*.xls *.xlsx *.csv);; AUDIO (*.wav)"));

    if (! filePath.isEmpty())
    {
        recentUsedFolder = QFileInfo(filePath).absolutePath();
        QMdiSubWindow *subWindow = findMdiChild(filePath);
        if (subWindow)
        {
            mdiArea->setActiveSubWindow(subWindow);
            return;
        }

        AISDocView *docView = new AISDocView;
        subWindow = mdiArea->addSubWindow(docView);
        if (docView->loadFile(filePath))
        {
            docView->showMaximized();
        }
        else
        {
            docView->close();
        }
    }
}

void MainWindow::saveFile()
{
}

void MainWindow::startSpeaking()
{
    if (speechAgent && audioRender)
    {
        AISDocView *curDocView = (AISDocView *)(mdiArea->activeSubWindow()->widget());
        QString text = curDocView->getContentText();
        if (text.isEmpty())
        {
            return;
        }
        if (AISpeechAgent::SAR_OK == speechAgent->speakText(text.toUtf8().constData()))
        {
            audioRender->play("aisReader.wav");
        }
        else
        {
            QMessageBox msgBox;
            msgBox.setText("Sorry, speech engine encounts error!");
            msgBox.exec();
        }
    }
}

void MainWindow::stopSpeaking()
{

}

void MainWindow::speechSetting()
{

}

void MainWindow::setActiveSubWindow(QWidget *subWindow)
{
    if (! subWindow)
    {
        return;
    }
    mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(subWindow));
}

QMdiSubWindow *MainWindow::findMdiChild(const QString &filePath)
{
    QString canonicalFilePath = QFileInfo(filePath).canonicalFilePath();
    foreach (QMdiSubWindow *subWindow, mdiArea->subWindowList())
    {
        AISDocView *docView = qobject_cast<AISDocView *>(subWindow->widget());
        QString existCanonicalFilePath = QFileInfo(docView->getCurrentFilePath()).canonicalFilePath();
        if(existCanonicalFilePath == canonicalFilePath)
        {
            return subWindow;
        }
    }
    return NULL;
}
